package ipcards;

import ipcards.rulesets.*;
import ipcards.net.Client;
import ipcards.net.ServerModel;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Point;
import java.util.Collections;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;


/**
 * Represents a table for playing card games on. Can Contain a {@link Deck} or a {@link Game}.
 * 
 * @author Ricky Vincent
 */
public class Table {
	
	private Room room;
	public GameList gamelist;
	public Game game;
	private char gamecode;
	public Dimension size;
	public Rectangle bounds;
	private int highestID = 0;
	private Player proxyPlayer;
	public ServerModel sModel;
	public HashMap<Integer, String> allPlayers;
	public int turn = 0;
	public int addDecksNumber = 0;
	
	public CardSet cards = new CardSet();
	//public CardSetControl cardGroups = new CardSetControl(cards);
	public LinkedList<Card> drawingList = new LinkedList<Card>();
	
	
	/**
	 * Constructs a new empty {@link Table} object.
	 */
	public Table() {
		setSize(new Dimension(1000,1000));
		proxyPlayer = new Player("Table");
		gamelist = new GameList();
		System.out.println("creating table");
		allPlayers = new HashMap<Integer, String>();
	}
	
	public void addDeck(Deck deck) {
		addNewCards(deck, new Point(15,15));
	}
	
	public void addDeck(Deck deck, Point point) {
		addNewCards(deck, point);
	}
	
	public void setRoom(Room room) {
		this.room = room;
	}
	
	public Room getRoom() {
		return room;
	}
	
	/**
	* Adds new cards at a certain point
	*/
	public void addNewCards(CardSet cs, Point point) {
		int cardsadded = 1;
		
		for (Card c: cs) {
			c.setID(highestID++);
			c.setTable(this);
			c.setLocation(point);
			cards.add(c);
			cardsadded++;
		}
	}
	
	/**
	* Adds new cards to the table
	*/
	public void addCards(CardSet cs) {
		cards.addAll(cs);
	
		//update highestID
		for(Card c: cards) {
			highestID = Math.max(highestID, c.getID());
		}
	}
	
	public void removeCards(CardSet cs) {
		cards.removeAll(cs);
	}
	
	public void removeAllCards() {
		cards.clear();
		highestID = 0;
	}
	
	//usually called server end
	public void newGame(String name, Client source) {	
		removeAllCards();
		if((name.toLowerCase()).equals("chase the ace")) {
			game = new ChaseTheAceGame(room.controller.getPlayerModel(), room, source);
			gamecode = GameList.CTA;
		}	
		if((name.toLowerCase()).equals("three up three down")) {
			game = new ThreeUpThreeDownGame(room.controller.getPlayerModel(), room, source);

System.out.println("numis"+addDecksNumber);
sModel.addDecks = addDecksNumber;			
			gamecode = GameList.TUTD;
		}
		if((name.toLowerCase()).equals("free play")){
			game = new FreePlayGame(room.controller.getPlayerModel(), room, source);
			gamecode = GameList.FP;
		}
	}
	
	//usually called client end
	public void newGame(String name, Client source, int numDecksAdded) {	
		removeAllCards();
		if((name.toLowerCase()).equals("chase the ace")) {
			game = new ChaseTheAceGame(room.controller.getPlayerModel(), room, source);
			gamecode = GameList.CTA;
		}	
		if((name.toLowerCase()).equals("three up three down")) {
			game = new ThreeUpThreeDownGame(room.controller.getPlayerModel(), room, source, numDecksAdded);
System.out.println("numis"+addDecksNumber);
//sModel.addDecks = addDecksNumber;	
			gamecode = GameList.TUTD;
		}
		if((name.toLowerCase()).equals("free play")){
			game = new FreePlayGame(room.controller.getPlayerModel(), room, source);
			gamecode = GameList.FP;
		}
	}
			
	/**
	 * @param game The {@link Game} to set.
	 */
	public void setGame(Game game) {
		this.game = game;
	}
	
	
	public void setSize(Dimension d){
		size = d;
		bounds = new Rectangle(size);
	}
	
	public boolean isInBounds(Rectangle c) {
		return bounds.contains(c);
	}
	
	public Player getPlayer() {
		return proxyPlayer;
	}
	
	
	/**
	 * Creates a CardSet from a delimited string of ID's
	 * @param ids The string of ID's separated by <code>PlayerAction.DEL</code>
	 */
	public CardSet getCardSetFromIDs(String ids) {
	
		if(ids == null || ids == "")
			return new CardSet();
		
		CardSet ret = new CardSet();
		String[] args = ids.trim().split(ipcards.events.PlayerAction.DEL + "");
		Vector<Card> newCards = new Vector<Card>();
		
		for(int pos = 0; pos < args.length; ++pos) {
			if (args[pos].length() == 0) continue;
			newCards.add(cards.getCardFromID(Integer.parseInt(args[pos])));
		}	
		
		for(Card c: cards.ZValueOrder) {
			if(newCards.contains(c)) {
				ret.add(c);
			}
		}
		
		return ret;
	}
	
	/**
	 * Creates an ordered List of cards from a delimited string of ID's in the correct z-order
	 * @param ids The string of ID's separated by <code>PlayerAction.DEL</code>
	 */
	public Vector<Card> getCardSetFromIDsOrdered(String ids) {
	
		if(ids == null || ids == "")
			return new Vector<Card>();
		
		Vector<Card> ret = new Vector<Card>();
		String[] args = ids.trim().split(ipcards.events.PlayerAction.DEL + "");
		Vector<Card> newCards = new Vector<Card>();
		
		for(int pos = 0; pos < args.length; ++pos) {
			if (args[pos].length() == 0) continue;
			newCards.add(cards.getCardFromID(Integer.parseInt(args[pos])));
		}	
		
		for(Card c: cards.ZValueOrder) {
			if(newCards.contains(c)) {
				ret.add(c);
			}
		}
		
		return ret;
	}
}
